import { get, has, isObject, isString } from 'lodash-es'
import dayjs from 'dayjs'
import type { CellItem } from '@/api/modules/types/ent'

interface FilterObj {
  Type: string
  LogicOperator: number
  Filters: FilterItem[]
}

interface FilterItem {
  Type: string
  Value?: string[] | number[]
  FilterKey?: string
  StartTime?: string
  EndTime?: string
}

function processValue(value: any, item?: any) {
  const valueType = get(item, 'type', 'string')
  if (value === undefined || value === null) {
    return value
  }
  if (isString(value)) {
    return value.split(' ').filter(item => !!item)
  }
  else if (!Array.isArray(value)) {
    return [valueType === 'number' ? Number(value) : value]
  }
  else {
    return valueType === 'number' ? Number(value) : value
  }
}

interface FilterItemAndKey {
  Type: string
  FilterKey: string | null
  valueKey: string
  type?: string
  mutlip?: boolean
  ObjType?: string
}
type FilterItemType = string | FilterItemAndKey

export class QueryObj {
  public objType: string
  readonly Filters: FilterItemType[]
  public outCells: CellItem[]
  public objFilter: {
    Type: string
    LogicOperator: number
    Filters: FilterItem[]
  }

  [key: string]: any

  constructor(options: { objType: string, Filters: FilterItemType[] }) {
    this.objType = options.objType
    this.Filters = options.Filters
    this.outCells = [{ CellName: '企业所属环保局ID' },
      { CellName: '企业所属环保局名称' },
      { CellName: '单元所属责任单位ID' },
      { CellName: '单元所属责任单位名称' },
      { CellName: '单元名称' },
      { CellName: '企业所属国民经济行业编码' },
      { CellName: '企业所属国民经济行业名称' },
      { CellName: '企业监测设备数量' },
      { CellName: '企业总表数量' },
      { CellName: '企业生产设施设备数量' },
      { CellName: '企业治理设施设备数量' },
    ]
    this.objFilter = {
      Type: 'DIM.FilterCollection',
      LogicOperator: 0,
      Filters: [],
    }

    options.Filters.forEach((item) => {
      if (isString(item)) {
        this[item] = undefined
      }
      else {
        if (item.FilterKey && (item.FilterKey.includes('Time') || item.FilterKey.includes('Date'))) {
          this[item.valueKey] = []
        }
        else {
          this[item.valueKey] = undefined
        }
      }
    })
  }

  getQuery(): FilterObj {
    this.objFilter.Filters = this.Filters.map((item: any) => {
      const keyString = get(item, 'FilterKey', '')
      const TypeKey = get(item, 'Type') || item as string
      const valueKey = get(item, 'valueKey') || item as string
      const isTime = isString(TypeKey) && (TypeKey.includes('Time') || keyString.includes('Date'))
      if (isTime && isObject(item as any)) {
        const [StartTime, EndTime] = this[valueKey] && this[valueKey].length ? this[valueKey] : ['', '']
        return {
          Type: item.Type,
          FilterKey: keyString,
          StartTime,
          EndTime: EndTime ? dayjs(EndTime).add(1, 'day').format('YYYYMMDD') : '',
        }
      }
      else {
        const queryObj: any = {
          Type: TypeKey,
        }
        if (isObject(item as any) && item?.mutlip) {
          queryObj.Values = processValue(this[valueKey || TypeKey], item)
        }
        else {
          queryObj.Value = processValue(this[valueKey || TypeKey], item)
        }
        keyString && (queryObj.FilterKey = keyString)
        has(item, 'ObjType') && (queryObj.ObjType = item.ObjType)
        return queryObj
      }
    })

    return this.objFilter
  }
}

export interface FilterObjItem {
  ObjTypeKey: string
  Filter: FilterItem
}

export class FilterQuery {
  public ObjTypeKey: string
  public Filters: string[]
  [key: string]: any

  constructor({ ObjTypeKey, Filters }: { ObjTypeKey: string, Filters: string[] }) {
    this.ObjTypeKey = ObjTypeKey
    this.Filters = Filters

    Filters.forEach((key) => {
      this[key] = undefined
    })
  }

  getQuery(): FilterObjItem[] {
    const filters = this.Filters.map((key) => {
      return {
        ObjTypeKey: this.ObjTypeKey,
        Filter: {
          Type: key,
          Value: processValue(this[key]),
        },
      }
    })

    return filters
  }
}

interface FilterKey {
  ObjTypeKey: string
  Type: string
}

export class FilterQuery2 {
  public Filters: FilterKey[]
  [key: string]: any

  constructor({ Filters }: { Filters: FilterKey[] }) {
    this.Filters = Filters

    Filters.forEach((item) => {
      this[item.Type] = undefined
    })
  }

  getQuery(): FilterObjItem[] {
    const filters = this.Filters.map((item) => {
      return {
        ObjTypeKey: item.ObjTypeKey,
        Filter: {
          Type: item.Type,
          Value: processValue(this[item.Type], item),
        },
      }
    })

    return filters
  }
}
